home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
User's Choice Windows CD
/
User's Choice Windows CD (CMS Software)(1993).iso
/
misc1
/
iv26_w30.zip
/
SOURCES
/
STREDITO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-21
|
11KB
|
356 lines
/*
* Copyright (c) 1987, 1988, 1989 Stanford University
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Stanford not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. Stanford makes no representations about
* the suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
* IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* StringEditor - interactive editor for character strings
*/
#include <InterViews/bitmap.h>
#include <InterViews/button.h>
#include <InterViews/cursor.h>
#include <InterViews/font.h>
#include <InterViews/painter.h>
#include <InterViews/sensor.h>
#include <InterViews/shape.h>
#include <InterViews/streditor.h>
#include <InterViews/textbuffer.h>
#include <InterViews/textdisplay.h>
#include <InterViews/Bitmaps/hand.bm>
#include <InterViews/Bitmaps/handm.bm>
#include <InterViews/Bitmaps/lfast.bm>
#include <InterViews/Bitmaps/lfastm.bm>
#include <InterViews/Bitmaps/rfast.bm>
#include <InterViews/Bitmaps/rfastm.bm>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
static const int BUFFERSIZE = 1000;
StringEditor::StringEditor (
ButtonState* s, const char* samp, const char* done
) {
Init(s, samp, done);
}
StringEditor::StringEditor (
const char* name, ButtonState* s, const char* samp, const char* done
) {
SetInstance(name);
Init(s, samp, done);
}
void StringEditor::Init (ButtonState* s, const char* samp, const char* d) {
SetClassName("StringEditor");
sample = samp;
size = BUFFERSIZE;
buffer = new char[size];
text = new TextBuffer(buffer, 0, size);
left = 0;
right = 0;
subject = s;
if (subject != nil) {
subject->Attach(this);
}
done = d;
display = new TextDisplay();
display->CaretStyle(NoCaret);
input = new Sensor();
input->Catch(KeyEvent);
input->Catch(DownEvent);
Message(sample);
}
StringEditor::~StringEditor () {
if (subject != nil) {
subject->Detach(this);
}
delete text;
delete buffer;
delete display;
}
static Cursor* handCursor;
static Cursor* leftCursor;
static Cursor* rightCursor;
void StringEditor::Reconfig () {
if (handCursor == nil) {
Bitmap hand(
hand_bits, hand_width, hand_height, hand_x_hot, hand_y_hot
);
Bitmap handmask(hand_mask_bits, hand_mask_width, hand_mask_height);
Bitmap left(
lfast_bits, lfast_width, lfast_height, lfast_x_hot, lfast_y_hot
);
Bitmap leftmask(lfast_mask_bits, lfast_mask_width, lfast_mask_height);
Bitmap right(
rfast_bits, rfast_width, rfast_height, rfast_x_hot, rfast_y_hot
);
Bitmap rightmask(rfast_mask_bits, rfast_mask_width, rfast_mask_height);
handCursor = new Cursor(
&hand, &handmask, output->GetFgColor(), output->GetBgColor()
);
leftCursor = new Cursor(
&left, &leftmask, output->GetFgColor(), output->GetBgColor()
);
rightCursor = new Cursor(
&right, &rightmask, output->GetFgColor(), output->GetBgColor()
);
}
Font* f = output->GetFont();
shape->Rect(f->Width(sample), f->Height());
shape->Rigid(hfil, hfil, 0, 0);
display->LineHeight(f->Height());
}
void StringEditor::Resize () {
display->Draw(output, canvas);
display->Resize(0, 0, xmax, ymax);
Select(left, right);
}
void StringEditor::Redraw (Coord l, Coord b, Coord r, Coord t) {
display->Draw(output, canvas);
display->Redraw(l, b, r, t);
}
void StringEditor::Message (const char* t) {
text->Delete(text->BeginningOfText(), text->Length());
text->Insert(0, t, strlen(t));
int bol = text->BeginningOfLine(0);
int eol = text->EndOfLine(0);
display->Draw(output, canvas);
display->ReplaceText(0, text->Text(bol, eol), eol - bol);
Select(eol);
}
void StringEditor::Select (int l) {
Select(l, l);
}
void StringEditor::Select (int l, int r) {
display->Draw(output, canvas);
int origin = display->Left(0, 0);
if (display->Left(0, r - 1) < 0) {
origin += xmax/2 - display->Left(0, r - 1);
} else if (display->Right(0, r + 1) > xmax) {
origin += xmax/2 - display->Right(0, r + 1);
}
origin = min(0, max(min(0, xmax - display->Width()), origin));
display->Scroll(0, origin, ymax);
DoSelect(l, r);
}
void StringEditor::DoSelect (int l, int r) {
display->Draw(output, canvas);
if (l > r) {
int tmp = r;
r = l;
l = tmp;
}
l = max(l, text->BeginningOfLine(left));
r = min(r, text->EndOfLine(right));
if (r < left || l > right) {
if (right > left) {
display->Style(0, left, 0, right-1, Plain);
}
if (r > l) {
display->Style(0, l, 0, r-1, Reversed);
}
} else {
if (l < left) {
display->Style(0, l, 0, left-1, Reversed);
} else if (l > left) {
display->Style(0, left, 0, l-1, Plain);
}
if (r > right) {
display->Style(0, right, 0, r-1, Reversed);
} else if (r < right) {
display->Style(0, r, 0, right-1, Plain);
}
}
left = l;
right = r;
if (left == right) {
display->Caret(0, left);
} else {
display->Caret(-1, 0);
}
}
void StringEditor::Edit () {
Event e;
e.target = nil;
e.eventType = EnterEvent;
Handle(e);
}
void StringEditor::Edit (const char* t, int l, int r) {
Message(t);
Select(l, r);
Edit();
}
const char* StringEditor::Text () {
return text->Text();
}
boolean StringEditor::HandleChar (char c) {
if (strchr(done, c) != nil) {
if (subject != nil) {
subject->SetValue(c);
}
return true;
} else {
switch (c) {
case SEBeginningOfLine:
Select(text->BeginningOfLine(left));
break;
case SEEndOfLine:
Select(text->EndOfLine(right));
break;
case SESelectAll:
Select(text->BeginningOfText(), text->EndOfText());
break;
case SESelectWord:
Select(
text->BeginningOfWord(text->PreviousCharacter(left)), right
);
break;
case SEPreviousCharacter:
Select(text->PreviousCharacter(left));
break;
case SENextCharacter:
Select(text->NextCharacter(right));
break;
case SEDeleteNextCharacter:
if (left == right) {
right = text->NextCharacter(right);
}
InsertText("", 0);
break;
case SEDeletePreviousCharacter:
case SEDeletePreviousCharacterAlt:
if (left == right) {
left = text->PreviousCharacter(left);
}
InsertText("", 0);
break;
default:
if (!iscntrl(c)) {
InsertText(&c, 1);
}
break;
}
return false;
}
}
void StringEditor::InsertText (const char* t, int len) {
display->Draw(output, canvas);
if (left != right) {
text->Delete(left, right-left);
display->DeleteText(0, left, right-left);
}
text->Insert(left, t, len);
display->InsertText(0, left, t, len);
int l = left;
while (len > 0) {
l = text->NextCharacter(l);
--len;
}
Select(l);
}
void StringEditor::Handle (Event& e) {
boolean done = false;
display->Draw(output, canvas);
display->CaretStyle(BarCaret);
do {
switch (e.eventType) {
case KeyEvent:
if (e.len != 0) {
done = HandleChar(e.keystring[0]);
}
break;
case DownEvent:
if (e.target == this) {
int origin = display->Left(0, 0);
int width = display->Width();
if (e.button == LEFTMOUSE) {
int start = display->LineIndex(0, e.x);
do {
if (e.x < 0) {
origin = min(0, origin - e.x);
} else if (e.x > xmax) {
origin = max(xmax - width, origin - (e.x - xmax));
}
display->Scroll(0, origin, ymax);
DoSelect(start, display->LineIndex(0, e.x));
Poll(e);
} while (e.leftmouse);
} else if (e.button == MIDDLEMOUSE) {
Cursor* origCursor = GetCursor();
SetCursor(handCursor);
int x = e.x;
do {
origin += e.x - x;
origin = min(0, max(min(0, xmax - width), origin));
display->Scroll(0, origin, ymax);
x = e.x;
Poll(e);
} while (e.middlemouse);
SetCursor(origCursor);
} else if (e.button == RIGHTMOUSE) {
Cursor* origCursor = GetCursor();
int x = e.x;
do {
origin += x - e.x;
origin = min(0, max(min(0, xmax - width), origin));
display->Scroll(0, origin, ymax);
if (e.x - x < 0) {
SetCursor(leftCursor);
} else {
SetCursor(rightCursor);
}
Poll(e);
} while (e.rightmouse);
SetCursor(origCursor);
}
} else {
UnRead(e);
done = true;
}
break;
}
if (!done) {
Read(e);
}
} while (!done);
display->CaretStyle(NoCaret);
}